package com.beta.cat.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.util.List;
import java.util.regex.Pattern;

/**
 * 请求参数处理工具类
 *
 * @author kevin_zhang
 * @date 2018/7/4
 */
@Slf4j
public class RequestParamUtil {

    /**
     * 获取请求参数
     *
     * @param req
     * @param paramName
     * @return
     */
    private static String getParameter(HttpServletRequest req, String paramName) {
        String ret = req.getParameter(paramName);
        if (StringUtils.isEmpty(ret)) {
            //针对从 getParameter 无法获取到请求参数的极端情况 -S
            try {
                String keyStr = paramName + "=";
                String queryStr = req.getQueryString();
                if (StringUtils.isNotBlank(queryStr)) {
                    queryStr = URLDecoder.decode(req.getQueryString(), "UTF-8");
                    String[] resultArr = queryStr.split("&");
                    for (String str : resultArr) {
                        if (str.contains(keyStr)) {
                            ret = str.replace(keyStr, "");
                            break;
                        }
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            //针对从 getParameter 无法获取到请求参数的极端情况 -E
        }
        return ret;
    }

    /**
     * 获取请求参数
     *
     * @param req
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getRequestParam(HttpServletRequest req, String name, Class<T> clazz) {
        return getRequestParam(req, name, clazz, null);
    }

    /**
     * 获取请求参数
     *
     * @param req
     * @param name
     * @param clazz
     * @param defaultValue
     * @param <T>
     * @return
     */
    public static <T> T getRequestParam(HttpServletRequest req, String name, Class<T> clazz, T defaultValue) {
        try {
            String jsonStr = getParameter(req, name);
            if (StringUtils.isNotBlank(jsonStr)) {
                return JsonUtil.parseObject(jsonStr, clazz);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return defaultValue;
    }

    /**
     * 获取请求参数
     *
     * @param req
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> getRequestParamList(HttpServletRequest req, String name, Class<T> clazz) {
        return getRequestParamList(req, name, clazz, null);
    }

    /**
     * 获取请求参数
     *
     * @param req
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> getRequestParamList(HttpServletRequest req, String name, Class<T> clazz, List<T> defaultValue) {
        try {
            String data = getParameter(req, name);
            if (StringUtils.isNotBlank(data)) {
                return JsonUtil.parseObjectList(data, clazz);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return defaultValue;
    }

    /**
     * 获取请求头参数
     *
     * @param req
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getHeaderParam(HttpServletRequest req, String name, Class<T> clazz) {
        return getHeaderParam(req, name, clazz, null);
    }

    /**
     * 获取请求头参数
     *
     * @param req
     * @param name
     * @param clazz
     * @param defaultValue
     * @param <T>
     * @return
     */
    public static <T> T getHeaderParam(HttpServletRequest req, String name, Class<T> clazz, T defaultValue) {
        try {
            String jsonStr = req.getHeader(name);
            if (StringUtils.isNotBlank(jsonStr)) {
                jsonStr = URLDecoder.decode(jsonStr, "UTF-8");
            }
            return JsonUtil.parseObject(jsonStr, clazz, defaultValue);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return defaultValue;
    }

    /**
     * 获取请求User-Agent
     *
     * @param req
     * @return
     */
    public static String getUserAgent(HttpServletRequest req) {
        String ua = "";
        try {
            if (StringUtils.isNotBlank(req.getHeader("user-agent"))) {
                ua = req.getHeader("user-agent");
            } else if (StringUtils.isNotBlank(req.getHeader("User-Agent"))) {
                ua = req.getHeader("User-Agent");
            } else if (StringUtils.isNotBlank(req.getHeader("user-Agent"))) {
                ua = req.getHeader("user-Agent");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return ua;
    }

    /**
     * 获取客户端请求的IP地址，优先获取公网IP。
     *
     * @param req
     * @return
     */
    public static String getClientIp(HttpServletRequest req) {
        String ret = "";
        try {
            String ipAddress = "";
            String[] headers = {"X-Real-IP", "x-forwarded-for", "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP"};
            String unknown = "unknown";
            for (String header : headers) {
                ipAddress = req.getHeader(header);
                if (StringUtils.isBlank(ipAddress) || unknown.equalsIgnoreCase(ipAddress)) {
                    continue;
                }
                ret = ipAddress;
                //如果追加了多个ip，找出其中的公网ip
                String[] ips = ipAddress.split(",");
                String tmp = ips[ips.length - 1];
                for (String ip : ips) {
                    if (StringUtils.isBlank(ip)) {
                        continue;
                    }
                    ip = StringUtils.trim(ip);
                    if (isLocalIp(ip)) {
                        continue;
                    }
                    tmp = ip;
                    break;
                }
                ret = tmp;
                if (!isLocalIp(ret)) {
                    break;
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return ret;
    }

    private static Pattern ipv4Pattern = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");

    private static boolean isLocalIp(String ip) {
        if (!ipv4Pattern.matcher(ip).matches()) {
            return true;//不是IP地址，一律认为不是公网
        }
        if (ip.startsWith("127.0.0.1") || ip.startsWith("10.") || ip.startsWith("192.168.") || ip.startsWith("172.")) {
            if (ip.startsWith("172.")) {
                //172的局域网范围是：172.16~172.31
                try {
                    int part = Integer.parseInt(ip.split("\\.")[1].trim());
                    if (part > 15 && part < 32) {
                        return true;
                    }
                } catch (Exception e) {
                }
            } else {
                return true;//局域网IP不需要
            }
        }
        return false;
    }


    public static String getIpAdress() {
        InetAddress ip4 = null;
        try {
            ip4 = Inet4Address.getLocalHost();
        } catch (Exception e) {
            log.error("get localhost ip error:", e);
            return "127.0.0.1";
        }
        return ip4.getHostAddress();

    }

    /**
     * 手机号验证
     *
     * @param str
     * @return 验证通过返回true
     */
    public static boolean isMobile(String str) {
        if (StringUtils.isBlank(str)) {
            return false;
        }
        return Pattern.matches("^1[3-9]\\d{9}$", str);
    }
}
